package com.wl.api.service.system.impl;

import static com.wl.api.common.utils.PageInfo.transfromPage;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.wl.api.common.utils.BeanUtils;
import com.wl.api.common.utils.CollectionUtil;
import com.wl.api.common.utils.ObjectUtil;
import com.wl.api.common.utils.PageInfo;
import com.wl.api.common.utils.StringUtil;
import com.wl.api.dto.system.SecurityChannelDTO;
import com.wl.api.dto.system.SecurityGradeDTO;
import com.wl.api.dto.system.SecurityGradePriceDTO;
import com.wl.api.mapper.system.SecurityGradeMapper;
import com.wl.api.model.system.SecurityChannel;
import com.wl.api.model.system.SecurityChannelAreaLadderPrice;
import com.wl.api.model.system.SecurityGrade;
import com.wl.api.model.system.SecurityGradePrice;
import com.wl.api.service.system.ISecurityChannelService;
import com.wl.api.service.system.ISecurityGradePriceService;
import com.wl.api.service.system.ISecurityGradeService;

/**
 *
 * SecurityGrade 表数据服务层接口实现类
 *
 */
@Service
public class SecurityGradeServiceImpl extends ServiceImpl<SecurityGradeMapper, SecurityGrade> implements ISecurityGradeService {

	@Autowired
	ISecurityGradePriceService gradePriceService;
	@Autowired
	ISecurityChannelService channelService;
	
	@Transactional
	public Long insertGradePrice(SecurityGradeDTO param) {
		SecurityGrade grade = BeanUtils.copyProperties(param, SecurityGrade.class);
		insert(grade);
		List<SecurityGradePrice> priceEntities = param.getChannelFeeRebateList().parallelStream().
				map(s -> BeanUtils.copyProperties(s, SecurityGradePrice.class).updateMsg(grade.getId())).collect(Collectors.toList()); 
		gradePriceService.insertBatch(priceEntities);
		return grade.getId();
	}
	
	@Transactional
	public void updateGradePrice(SecurityGradeDTO param) {
		Assert.isTrue(param.getId() != null);		
		List<SecurityGradePrice> source =  gradePriceService.getGradePricesByParam(SecurityGradePriceDTO.builder().gradeId(param.getId()).build());
		List<Long> delIds = new ArrayList<Long>();
		List<SecurityGradePrice> updateList = param.getChannelFeeRebateList().parallelStream().filter(s -> !ObjectUtil.isEmpty(s.getId())).map(x -> BeanUtils.copyProperties(x, SecurityGradePrice.class)).collect(Collectors.toList()); 
		List<SecurityGradePrice> insertList = param.getChannelFeeRebateList().parallelStream().filter(s -> ObjectUtil.isEmpty(s.getId())).map(x -> BeanUtils.copyProperties(x, SecurityGradePrice.class)).collect(Collectors.toList());
		//del 
		if (!CollectionUtil.isEmpty(source)) {
			for(SecurityGradePrice sc: source) {
				if (CollectionUtil.isEmpty(updateList)) {
					delIds.add(sc.getId());
					continue;
				}
				if (updateList.parallelStream().noneMatch(s -> Objects.equals(s.getId(), sc.getId()))) {
					delIds.add(sc.getId());
					continue;
				}
			}
		}
		
		if(!CollectionUtil.isEmpty(delIds)) {
			gradePriceService.deleteBatchIds(delIds);
		}
		if (!CollectionUtil.isEmpty(updateList)) {
			gradePriceService.updateBatchById(updateList);
		}
		if (!CollectionUtil.isEmpty(insertList)) {
			gradePriceService.insertBatch(insertList);
		}
	}
	
	@Transactional
	public void delGrade(Long gradeId) {
		deleteById(gradeId);
		gradePriceService.delete(new EntityWrapper<SecurityGradePrice>().where("grade_id", gradeId));
	}
	
	public PageInfo<SecurityGradeDTO> getItemList(SecurityGradeDTO param) {
		Wrapper<SecurityGrade> wrapper = new EntityWrapper<>();
		wrapper.where("1=1");
		if (StringUtil.isEmpty(param.getName())) {
			wrapper.like("name", param.getName());
		}
		Page<SecurityGrade> page = selectPage(new Page<>(param.getPage(), param.getPageSize(), "update_time desc"), wrapper);
		return transfromPage(SecurityGradeDTO.class, page);
	}
	
	/*@SuppressWarnings("unchecked")
	public PageInfo<SecurityGradePriceDTO> getItemList(SecurityGradeDTO param) {
		Map<Long, String>  gradeNameMap = new HashMap<Long, String>(),  channelNameMap = new HashMap<Long, String>();
		
		Wrapper<SecurityGradePrice> wrapper = new EntityWrapper<>();
		wrapper.where("1=1");
		
		if (!StringUtil.isEmpty(param.getName())) {
			List<SecurityGrade> gradeList = selectList(new EntityWrapper<SecurityGrade>().like("name", param.getName())); 
			if (CollectionUtils.isEmpty(gradeList)) {
				return  PageInfo.getInstance();
			}
			wrapper.in("grade_id", gradeList.parallelStream().map(SecurityGrade::getId).collect(Collectors.toList()));
			gradeNameMap = gradeList.parallelStream().collect(Collectors.toMap(SecurityGrade::getId, SecurityGrade::getName));
		}
		if (param.getChannelId() != null) {
			wrapper.andNew("channel_id",  param.getChannelId());
		}
		
		Page<SecurityGradePrice> page = gradePriceService.selectPage(new Page<>(param.getPage(), param.getPageSize(), "update_time desc"), wrapper);
		PageInfo<SecurityGradePriceDTO> pageInfo =  transfromPage(SecurityGradePriceDTO.class, page);
		
		if (!CollectionUtil.isEmpty(pageInfo.getItems())) {
			channelNameMap = channelService.selectBatchIds(pageInfo.getItems().parallelStream().map(SecurityGradePriceDTO::getChannelId).distinct().collect(Collectors.toList())).parallelStream().collect(Collectors.toMap(SecurityChannel::getId, SecurityChannel::getName));
			
			for(SecurityGradePriceDTO dd: pageInfo.getItems()) {
				dd.setName(gradeNameMap.get(dd.getGradeId()));
				dd.setChannelName(channelNameMap.get(dd.getChannelId()));
			}
		}
		
		return pageInfo;
	}
*/
}